package com.ken.mall.comm;

import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.List;
import java.util.Set;

/**
 *  controller 增强器
 *  全局异常处理
 *  @author ken
 *  @since 2018/05/14
 */
@ControllerAdvice
@Slf4j
public class CommonExceptionAdvice {

    private ObjectError error;

    /**
     * 未捕获异常
     * @param request
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public ServerResponse defaultExceptionHandler(HttpServletRequest request, Exception ex){
        StringBuffer url = request.getRequestURL();
        log.error("系统错误，请求URL"+url.toString()+"错误：",ex);
        return ServerResponse.createByErrorMessage("系统错误，请重试或联系管理员");
    }

    /**
     * 请求模式错误
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public ServerResponse requestMethodExceptionHandler(HttpRequestMethodNotSupportedException ex){
        return ServerResponse.createByErrorMessage(ex.getLocalizedMessage());
    }

    @ResponseBody
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    public ServerResponse missingRequestParameterExceptionHandler(MissingServletRequestParameterException ex){
        return ServerResponse.createByErrorMessage(ex.getLocalizedMessage());
    }

    /**
     * 方法级别参数校验全局处理
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = ConstraintViolationException.class)
    public ServerResponse constraintViolationException(ConstraintViolationException ex){
        Set<ConstraintViolation<?>> violations = ex.getConstraintViolations();
        StringBuffer message =  new StringBuffer();
        for (ConstraintViolation<?> item : violations){
            message.append(item.getMessage());
            message.append("\n");
        }
        return ServerResponse.createByErrorMessage(message.toString());
    }

    /**
     * model级别参数校验全局处理
     * @param ex
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = BindException.class)
    public ServerResponse constraintViolationException(BindException ex){
        BindingResult result = ex.getBindingResult();
        String message = null;
        if (result.hasErrors()){
            List<ObjectError> allErrors = result.getAllErrors();
            StringBuffer sb = new StringBuffer();
            for (ObjectError error : allErrors){
                sb.append(error.getDefaultMessage());
                sb.append("\n");
            }
            message = sb.toString();
        }
        return ServerResponse.createByErrorMessage(message);
    }

}
